//
//  NetworkTools.swift
//  TWeibo
//
//  Created by wtw on 15/7/29.
//  Copyright © 2015年 wtw. All rights reserved.
//

import UIKit
import AFNetworking

//错误的类别标记
private let TWerrorDomainName = "hello error"

// MARK: - 定义枚举错误信息
/// 网络访问错误信息 - 枚举，是定义一组类似的值
///swift 中枚举可以定义函数和属性，跟 ‘类’有点像
//OC中枚举通常是整数，但是在swift中任意类型都可以的
private enum TWNetworkError: Int {
    case emptyDataError = -1
    case emptyTokenError = -2
    
    //错误描述
    private var description: String {
        //self就是对应的枚举
        switch self {
        case .emptyDataError:
            return "空数据"
        case .emptyTokenError:
            return"AccessToken 错误"
        }
    }
    //枚举的函数形式
    private func error() ->NSError {
        return NSError(domain: TWerrorDomainName, code: rawValue, userInfo: [TWerrorDomainName: description])
    }
}

///网络访问方法
private enum TWNetworkMethod: String {
    case GET = "GET"
    case POST = "POST"
}


//MARK: -网络工具类
class NetworkTools: AFHTTPSessionManager {
    
    //MARK: - 应用程序信息
    private let clientId = "1085133553"
    private let appSecret = "308ab4a3d3da890269509f4cc4b52485"
    //回调地址
    let redirectUri = "http://www.baidu.com"
    
    // MARK: - 类型定义
    //完成回调类型  typealias:起个别名
    typealias TWFinshedCallBack = (result: [String: AnyObject]?,error: NSError?) ->()
    
    //单例
    static let shareNetworkTools: NetworkTools = {
        
        let baseURL = NSURL(string: "https://api.weibo.com/")!
        let instance = NetworkTools(baseURL: baseURL)
        
        /// 设置数据解析数据类型
        instance.responseSerializer.acceptableContentTypes = NSSet(objects: "application/json", "text/json", "text/javascript", "text/plain") as Set<NSObject>
        
        return instance
        
        }()
    
    // 检查并生成 token 字典
    private func checkToken(finished:TWFinshedCallBack) ->[String: AnyObject]? {
        //判断token 是否存在
        if UserAcount.sharedUserAccount?.access_token == nil {
            //错误回调
            let error = TWNetworkError.emptyTokenError.error()
            print(error)
            finished(result: nil, error: error)
            return nil
        }
        //生成 token 字典返回
        return ["access_token": UserAcount.sharedUserAccount!.access_token!]
    }
    
    //MARK: - 加载微博数据
    /*
    刷新时需要扩展的参数
    since_id 返回ID比since_id大的未必（即比since_id时间晚的微博),默认是0
    max_id   返回ID ‘小于’ ‘等于’ max_id的微博，默认是0
    */
    
    func loadStatuses(since_id:Int,max_id: Int, finished: TWFinshedCallBack) {
        //判断token 是否存在,为 nil直接返回
        //guard 是swift 2.0新语法，跟 if let 刚好相反
        //leth获得变量，后续可以直接使用，而且不一定为nil
        guard var params = checkToken(finished) else {
            //params 在这里 一般为 nil 直接返回
            //checkToken 已经做了token为空的回调
            return
        }
        
        if since_id > 0 {
            params["since_id"] = since_id
        }
        if max_id > 0 {
            //减1是因为怕刷新下一组时会有一个重复
            params["max_id"] = max_id - 1
        }
        
        //代码运行至此，params 一定有值
        let urlString = "2/statuses/home_timeline.json"
        
        request(TWNetworkMethod.GET, urlString: urlString, params: params, finished: finished)
    }
    
    // MARK: - 加载用户信息方法
    /// 加载用户信息
    func loadUserInfo(uid: String, finished: (result: [String: AnyObject]?, error: NSError?) -> ()) {
        // guard 不仅可以用 let ，也可以用var
        guard var params = checkToken(finished) else {
            //parms 在此为nil ，一般直接返回
            return
        }
        let urlString = "2/users/show.json"
        params["uid"] = uid
        
        //发送网络请求
        //如果参数不正确，先用option + click 确认参数类型
        request(TWNetworkMethod.GET,urlString:urlString, params: params, finished: finished)
    }
    
    // MARK: - OAuth授权
    /// 加载授权页面
    //返回OAuthUrl的授权地址
    func oauthUrl() ->NSURL  {
        let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(clientId)&redirect_uri=\(redirectUri)"
        
        return NSURL(string: urlString)!
    }
    
    /// 加载Token
    func loadAccessToken(code: String,finished:TWFinshedCallBack) {
        let urlString = "https://api.weibo.com/oauth2/access_token"
        let parames = ["client_id":clientId,
            "client_secret": appSecret,
            "grant_type": "authorization_code",
            "code":code,
            "redirect_uri":redirectUri]
        request(TWNetworkMethod.POST,urlString:urlString, params: parames, finished:finished)
    }
    
    private func request(Method:TWNetworkMethod, urlString: String, params: [String: AnyObject], finished: TWFinshedCallBack) {
        
        //1.定义成功的闭包
        let successCallBack:(NSURLSessionDataTask!,AnyObject!) ->Void = { (_, JSON) -> Void in
            
            if let result = JSON as? [String: AnyObject] {
                // 有结果的回调
                finished(result: result, error: nil)
            } else {
                // 没有错误，同时没有结果
                print("没有数据 \(Method) Request \(urlString)")
                
                finished(result: nil, error: TWNetworkError.emptyDataError.error())
            }
            
        }
        
        //2.定义失败的闭包
        let failedCallBack:(NSURLSessionDataTask!,NSError!)->Void = { (_, error) -> Void in
            print(error)
            
            finished(result: nil, error: error)
        }
        
        //3.根据 method 来选择执行的方法
        switch Method {
        case .GET:
            GET(urlString, parameters: params, success: successCallBack, failure: failedCallBack)
        case .POST:
            POST(urlString, parameters: params, success: successCallBack, failure: failedCallBack)
        }
    }
}
